package cn.edu.zut.soft.graduate.base.bo;

import cn.edu.zut.soft.basic.core.model.bo.CommonResult;
import cn.edu.zut.soft.basic.core.model.dao.Criteria;
import cn.edu.zut.soft.basic.core.model.dao.Example;
import cn.edu.zut.soft.basic.core.model.dao.Page;
import cn.edu.zut.soft.graduate.base.dao.BasicDAO;
import cn.edu.zut.soft.graduate.core.model.BaseModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.List;

/**
 * Created by chuchuang on 16/10/22.
 */
public abstract class BasicBOImpl<T extends BaseModel,Q extends Page> implements BasicBO<T,Q> {

    protected static final String DEL="del";
    protected static final Integer del = 0;

    protected Logger logger = LoggerFactory.getLogger(getClass());

    protected abstract BasicDAO<Integer,T> getDAO();

    @Override
    @Transactional
    public CommonResult<T> save(T t, String operator) {
        afterSave(t, operator);
        getDAO().insertSelective(t);
        T result = getDAO().selectByPrimaryKey(t.getId());
        Assert.notNull(result,"插入失败");
        return CommonResult.successReturn(result);
    }

    protected void afterSave(T t, String operator) {
        //保存创建修改人
        t.setCreateAuthor(operator);
        afterUpdate(t, operator);
        t.setDel(0);
    }


    @Override
    public T get(Integer id) {
        if (id != null && id > 0) {
            return getDAO().selectByPrimaryKey(id);
        }
        return null;
    }

    @Override
    @Transactional
    public CommonResult<T> update(T t, String operator) {
        afterUpdate(t, operator);
        getDAO().updateByPrimaryKeySelective(t);
        t = getDAO().selectByPrimaryKey(t.getId());
        Assert.notNull(t);
        return CommonResult.successReturn(t);
    }

    protected void afterUpdate(T t, String operator) {
        t.setUpdateAuthor(operator);
    }

    @Override
    public CommonResult<List<T>> findByQuery(Q q) {
        // FIXME: 16/10/29 将排序字段暴露了,望改正

        List<Criteria> criteriaList = Query(q);
        Example example = Example.createOfPage(q);
        for (Criteria c : criteriaList){
            example.or(c);
        }
        CommonResult<List<T>> commonResult = new CommonResult<>(true,getDAO().selectByExample(example));
        commonResult.setTotalCount(getDAO().countByExample(example.cleanPage()));
//        q.setCount(new Long(commonResult.getTotalCount()));
        return commonResult;
    }

    @Override
    public int countByQuery(Q q){
        List<Criteria> criteriaList = Query(q);
        Example example = Example.createOfPage(q);
        for (Criteria c : criteriaList){
            example.or(c);
        }
        return getDAO().countByExample(example);
    }

    protected abstract List<Criteria> Query(Q q);

    @Override
    @Transactional
    public CommonResult<T> delete(Integer id, String operator) {
        T t = getDAO().selectByPrimaryKey(id);
        if (t == null){
            return CommonResult.errorReturn("does not exist");
        }
        getDAO().deleteByPrimaryKey(id, operator);
        return CommonResult.successReturn(t);
    }
}
